package org.example.rowing.controller;

import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.rowing.controller.util.BaseController;
import org.example.rowing.controller.util.NavigationUtil;
import org.example.rowing.domain.*;
import org.example.rowing.enums.BoatTypeEnum;
import org.example.rowing.service.EventInfoService;
import org.example.rowing.service.RaceInfoService;
import org.example.rowing.service.ResultInfoService;
import org.example.rowing.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@Slf4j
public class ResultsInfoController extends BaseController {

    @FXML
    public ComboBox<Event> goldSearchComboBox;
    @FXML
    public TableColumn<GoldRankingVO, String> eventGoldColumn;
    @FXML
    public TableColumn<GoldRankingVO, String> teamGoldColumn;
    @FXML
    public TableColumn<GoldRankingVO, String> goldCountColumn;
    @FXML
    public TableColumn<GoldRankingVO, String> goldRankColumn;
    @FXML
    public ComboBox<Event> medalSearchComboBox;
    @FXML
    public TableColumn<MedalRankingVO, String> eventMedalColumn;
    @FXML
    public TableColumn<MedalRankingVO, String> teamMedalColumn;
    @FXML
    public TableColumn<MedalRankingVO, String> goldMedalColumn;
    @FXML
    public TableColumn<MedalRankingVO, String> bronzeMedalColumn;
    @FXML
    public TableColumn<MedalRankingVO, String> silverMedalColumn;
    @FXML
    public TableColumn<MedalRankingVO, String> totalMedalColumn;
    @FXML
    public TableColumn<MedalRankingVO, String> medalRankColumn;
    @FXML
    public ComboBox<Event> scoreSearchComboBox;
    @FXML
    public TableColumn<ScoreRankingVO, String> teamScoreColumn;
    @FXML
    public TableColumn<ScoreRankingVO, String> eventScoreColumn;
    @FXML
    public TableColumn<ScoreRankingVO, String> totalScoreColumn;
    @FXML
    public TableColumn<ScoreRankingVO, String> scoreRankColumn;
    @FXML
    public ComboBox<Event> eventTypeComboBox;
    @FXML
    public ComboBox<Race> eventProjectComboBox;
    @FXML
    public ComboBox<String> roundComboBox;
    @FXML
    public TableColumn<RoundScoreVO, String> idResultColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> teamResultColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> athleteResultColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> roundResultColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> laneResultColumn;
    @FXML
    public TableColumn<RoundScoreVO, Double> resultResultColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> resultRankColumn;
    @FXML
    public TableView<GoldRankingVO> goldRankingTable;
    @FXML
    public TableView<MedalRankingVO> medalRankingTable;
    @FXML
    public TableView<ScoreRankingVO> scoreRankingTable;
    @FXML
    public TableView<RoundScoreVO> resultRankingTable;
    @FXML
    public Label exportGoldStatusLabel;
    @FXML
    public Label exportMedalStatusLabel;
    @FXML
    public Label exportScoreStatusLabel;
    @FXML
    public Label exportResultStatusLabel;
    @FXML
    private VBox sideNav;
    private ObservableList<GoldRankingVO> goldRankingList;
    private ObservableList<MedalRankingVO> medalRankingList;
    private ObservableList<ScoreRankingVO> scoreRankingList;
    private ObservableList<RoundScoreVO> resultRankingList;
    @FXML
    private Button btnResults;

    @Autowired
    private ResultInfoService resultInfoService;
    @Autowired
    private EventInfoService eventInfoService;
    @Autowired
    private RaceInfoService raceInfoService;


    @Override
    protected Button getButton() {
        return btnResults;
    }

    @Override
    public void initialize() {
        super.initialize();

        // 设置时间列的格式化显示
        resultResultColumn.setCellFactory(column -> new TableCell<RoundScoreVO, Double>() {
            @Override
            protected void updateItem(Double time, boolean empty) {
                super.updateItem(time, empty);

                if (empty || time == null) {
                    setText(null);
                } else {
                    // 格式化为 x1:x2.x3 格式
                    int minutes = (int) (time / 60);
                    int seconds = (int) (time % 60);
                    int hundredths = (int) ((time * 100) % 100);
                    setText(String.format("%d:%02d.%02d", minutes, seconds, hundredths));
                }
            }
        });

        // 设置表格列
        eventGoldColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getEvent().getName()));
        teamGoldColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getTeam().getName()));
        goldCountColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getGoldCount())));
        goldRankColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getGoldRank())));

        eventMedalColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getEvent().getName()));
        teamMedalColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getTeam().getName()));
        goldMedalColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getGoldCount())));
        silverMedalColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getSilverCount())));
        bronzeMedalColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getBronzeCount())));
        totalMedalColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getTotalCount())));
        medalRankColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getMedalRank())));

        eventScoreColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getEvent().getName()));
        teamScoreColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getTeam().getName()));
        totalScoreColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getTotalScore())));
        scoreRankColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getScoreRank())));

        idResultColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getRegistrationVO().getRegistrationId().toString()));
        teamResultColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getRegistrationVO().getTeam().getName()));
        athleteResultColumn.setCellValueFactory(cellData -> {
            // 为每个单元格单独处理：获取当前行的运动员列表
            List<RegistrationWithAthlete> athletes = cellData.getValue().getRegistrationVO().getAthletes();

            // 动态拼接当前行所有运动员姓名
            String joinedNames = athletes.stream()
                    .map(RegistrationWithAthlete::getAthleteName)
                    .collect(Collectors.joining("、"));

            return new SimpleStringProperty(joinedNames);
        });
        roundResultColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getRound()));
        laneResultColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getLane()));
        resultResultColumn.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<>(cellData.getValue().getScore()));
        resultRankColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getRank())));

        // 设置转换器，使下拉框只显示 name
        goldSearchComboBox.setConverter(new StringConverter<Event>() {
            @Override
            public String toString(Event event) {
                return event == null ? "" : event.getId() + ". " + event.getName();
            }
            @Override
            public Event fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        medalSearchComboBox.setConverter(new StringConverter<Event>() {
            @Override
            public String toString(Event event) {
                return event == null ? "" : event.getId() + ". " + event.getName();
            }
            @Override
            public Event fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        scoreSearchComboBox.setConverter(new StringConverter<Event>() {
            @Override
            public String toString(Event event) {
                return event == null ? "" : event.getId() + ". " + event.getName();
            }
            @Override
            public Event fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        eventTypeComboBox.setConverter(new StringConverter<Event>() {
            @Override
            public String toString(Event event) {
                return event == null ? "" : event.getId() + ". " + event.getName();
            }
            @Override
            public Event fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        eventProjectComboBox.setConverter(new StringConverter<Race>() {
            @Override
            public String toString(Race race) {
                return race == null ? "" : race.getId() + ". " + race.getName();
            }
            @Override
            public Race fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });

        // 初始化赛事列表（默认展示一些数据）
        // 填充下拉框
        List<EventVO> eventVOS = eventInfoService.showEventsByType(BoatTypeEnum.ROWING);
        List<Event> events = new ArrayList<>();
        for (EventVO eventVO : eventVOS) {
            Event event = new Event(eventVO.getId(), eventVO.getName(), null, null, null, BoatTypeEnum.fromDisplayName(eventVO.getBoatType()));
            events.add(event);
        }
        goldSearchComboBox.setItems(FXCollections.observableArrayList(events));
        medalSearchComboBox.setItems(FXCollections.observableArrayList(events));
        scoreSearchComboBox.setItems(FXCollections.observableArrayList(events));
        eventTypeComboBox.setItems(FXCollections.observableArrayList(events));
        // 默认选中第一个赛事，并加载其数据
        if (!events.isEmpty()) {
            goldSearchComboBox.getSelectionModel().select(0);
            medalSearchComboBox.getSelectionModel().select(0);
            scoreSearchComboBox.getSelectionModel().select(0);
            updateGoldTableForEvent(goldSearchComboBox.getSelectionModel().getSelectedItem());
            updateMedalTableForEvent(medalSearchComboBox.getSelectionModel().getSelectedItem());
            updateScoreTableForEvent(scoreSearchComboBox.getSelectionModel().getSelectedItem());
        }
        // 为下拉框添加监听器，用户选择其他赛事时更新表格数据
        goldSearchComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                updateGoldTableForEvent(newValue);
            }
        });
        medalSearchComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                updateMedalTableForEvent(newValue);
            }
        });
        scoreSearchComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                updateScoreTableForEvent(newValue);
            }
        });

        // 级联选择-轮次成绩
        // 2. 为赛事类型下拉框添加监听器，加载对应的比赛项目
        eventTypeComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                RaceVO raceVO = new RaceVO();
                raceVO.setEventId(newValue.getId());
                List<RaceVO> raceVOS = raceInfoService.showSearchedRaces(raceVO);
                List<Race> races = new ArrayList<>();
                for (RaceVO vo : raceVOS) {
                    Race race = new Race(vo.getId(), vo.getName(), vo.getEventVO().getId(), vo.getDistance(),
                            null, null, null, null, null, null, null, null,
                            null, null, null, null, vo.getIsLongDistance());
                    races.add(race);
                }
                eventProjectComboBox.setItems(FXCollections.observableArrayList(races));
                // 自动选中第一个项目（如果存在）
                if (!races.isEmpty()) {
                    eventProjectComboBox.getSelectionModel().select(0);
                }
            }
        });
        // 3. 为比赛项目下拉框添加监听器，加载对应的轮次
        eventProjectComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                List<String> rounds = List.of("预赛", "复赛", "1/4决赛", "半决赛", "决赛", "计时赛", "比赛结果");
                roundComboBox.setItems(FXCollections.observableArrayList(rounds));
                // 自动选中第一个轮次（如果存在）
                roundComboBox.getSelectionModel().select(0);
            }
        });
        // 4. 当轮次选择变化后，更新成绩表数据
        roundComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                updateResultTable();
            }
        });
        // 若需要在初始时就加载数据，可以先选中第一个赛事类型
        if (!events.isEmpty()) {
            eventTypeComboBox.getSelectionModel().select(0);
        }
    }

    private void updateResultTable() {
        Event event = eventTypeComboBox.getSelectionModel().getSelectedItem();
        Race race = eventProjectComboBox.getSelectionModel().getSelectedItem();
        String round = roundComboBox.getSelectionModel().getSelectedItem();
        // 根据所选赛事从数据库获取金牌榜数据
        RoundScoreVO roundScoreVO = new RoundScoreVO();
        roundScoreVO.setEventId(event.getId());
        roundScoreVO.setRaceId(race.getId());
        roundScoreVO.setRound(round);
        // 将过滤后的列表更新到表格
        resultRankingList = FXCollections.observableArrayList(resultInfoService.showSearchedRoundScoreRanking(roundScoreVO));
        resultRankingTable.setItems(resultRankingList);
        resultRankingTable.refresh();
    }

    private void updateGoldTableForEvent(Event event) {
        // 根据所选赛事从数据库获取金牌榜数据
        EventResultVO eventResultVO = new EventResultVO();
        eventResultVO.setEventId(event.getId());
        // 将过滤后的列表更新到表格
        goldRankingList = FXCollections.observableArrayList(resultInfoService.showSearchedGoldRankings(eventResultVO));
        goldRankingTable.setItems(goldRankingList);
        goldRankingTable.refresh();
    }

    private void updateMedalTableForEvent(Event event) {
        // 根据所选赛事从数据库获取金牌榜数据
        EventResultVO eventResultVO = new EventResultVO();
        eventResultVO.setEventId(event.getId());
        // 将过滤后的列表更新到表格
        medalRankingList = FXCollections.observableArrayList(resultInfoService.showSearchedMedalRankings(eventResultVO));
        medalRankingTable.setItems(medalRankingList);
        medalRankingTable.refresh();
    }

    private void updateScoreTableForEvent(Event event) {
        // 根据所选赛事从数据库获取金牌榜数据
        EventResultVO eventResultVO = new EventResultVO();
        eventResultVO.setEventId(event.getId());
        // 将过滤后的列表更新到表格
        scoreRankingList = FXCollections.observableArrayList(resultInfoService.showSearchedScoreRankings(eventResultVO));
        scoreRankingTable.setItems(scoreRankingList);
        scoreRankingTable.refresh();
    }

    @FXML
    private void handleNavButtonClick(ActionEvent event) throws IOException {
        log.info("当前触发事件为：{}",event);
        Button clickedButton = (Button) sideNav.getScene().getFocusOwner();
        NavigationUtil.navigateToScene(
                event,
                NavigationUtil.viewMap.get(clickedButton.getId()),
                "赛艇管理");
    }

    // 对皮划艇菜单点击的处理
    @FXML
    public void handleBoatTypeClick(ActionEvent event) throws IOException {
        log.info("切换到皮划艇界面");
        NavigationUtil.navigateToScene(
                (Stage) sideNav.getScene().getWindow(),
                "/fxml/canoeAndKayakViews/CKEventInfoView.fxml",
                "皮划艇管理");
    }

    @FXML
    private void handleExportResults(ActionEvent event) {
        // 根据触发导出操作的按钮确定需要导出的 TableView
        Button sourceButton = (Button) event.getSource();
        TableView<?> tableToExport = null;
        String fileNamePrefix = "";
        Label labelToExport = null;

        switch (sourceButton.getId()) {
            case "exportGoldResultsButton":
                tableToExport = goldRankingTable;
                fileNamePrefix = "GoldRanking";
                labelToExport = exportGoldStatusLabel;
                break;
            case "exportMedalResultsButton":
                tableToExport = medalRankingTable;
                fileNamePrefix = "MedalRanking";
                labelToExport = exportMedalStatusLabel;
                break;
            case "exportScoreResultsButton":
                tableToExport = scoreRankingTable;
                fileNamePrefix = "ScoreRanking";
                labelToExport = exportScoreStatusLabel;
                break;
            case "exportResultResultsButton":
                tableToExport = resultRankingTable;
                fileNamePrefix = "RoundResults";
                labelToExport = exportResultStatusLabel;
                break;
            default:
                return;
        }

        if (tableToExport == null) {
            return;
        }

        // 弹出文件保存对话框
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("保存导出文件");
        fileChooser.setInitialFileName(fileNamePrefix + ".xlsx");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Excel 文件", "*.xlsx"));
        File file = fileChooser.showSaveDialog(labelToExport.getScene().getWindow());

        if (file != null) {
            // 创建一个 Excel 工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("Sheet1");

            // 写入表头行
            Row headerRow = sheet.createRow(0);
            ObservableList<? extends TableColumn<?, ?>> columns = tableToExport.getColumns();
            for (int i = 0; i < columns.size(); i++) {
                TableColumn<?, ?> column = columns.get(i);
                org.apache.poi.ss.usermodel.Cell cell = headerRow.createCell(i);
                cell.setCellValue(column.getText());
                // 可选：设置样式
                CellStyle headerStyle = workbook.createCellStyle();
                Font font = workbook.createFont();
                font.setBold(true);
                headerStyle.setFont(font);
                cell.setCellStyle(headerStyle);
            }

            // 写入每一行数据
            ObservableList<?> items = tableToExport.getItems();
            for (int rowIndex = 0; rowIndex < items.size(); rowIndex++) {
                Row row = sheet.createRow(rowIndex + 1);
                Object item = items.get(rowIndex);
                for (int colIndex = 0; colIndex < columns.size(); colIndex++) {
                    TableColumn<?, ?> column = columns.get(colIndex);
                    Object cellData = ((TableColumn<Object, Object>) column).getCellData(item);
                    Cell cell = row.createCell(colIndex);
                    if (cellData != null) {
                        cell.setCellValue(cellData.toString());
                    } else {
                        cell.setCellValue("");
                    }
                }
            }

            // 自动调整每列宽度
            for (int i = 0; i < columns.size(); i++) {
                sheet.autoSizeColumn(i);
                // 获取当前列宽
                int currentWidth = sheet.getColumnWidth(i);
                // 增加额外宽度，例如增加 40% 的宽度
                int extraWidth = (int)(currentWidth * 0.4);
                sheet.setColumnWidth(i, currentWidth + extraWidth);
            }

            // 保存工作簿到文件
            try (FileOutputStream fos = new FileOutputStream(file)) {
                workbook.write(fos);
                workbook.close();
                labelToExport.setText("导出成功！");
            } catch (IOException e) {
                labelToExport.setText("导出失败: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
}
